package controller;

import helper.AngepassteException;
import helper.Mail;

import java.io.IOException;
import java.sql.SQLException;
import java.util.GregorianCalendar;
import java.util.Random;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.Benutzer;
import model.Gruppe;
import model.PwVergessenSchnittstelle;
import model.PwZuruecksetzenLink;

/**
 * Dieses Servlet dient dem Administrator zum Bearbeiten, Löschen und Erstellen
 * von Benutzern.
 */
@WebServlet({ "/BenutzerForm", "/benutzerform", "/benutzerform.html",
		"/benutzerform.php" })
public class BenutzerForm extends SessionControll {
	private static final long serialVersionUID = 1L;
	public static final String serverAdresse = "http://localhost:8080/";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public BenutzerForm() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		if (super.gruppePruefen(request, response, Gruppe.ADMIN)) {
			Benutzer b = null;
			System.out.println("benutzerId: "
					+ request.getParameter("benutzerId"));
			System.out.println("vorname: " + request.getParameter("vorname"));
			System.out.println("nachname: " + request.getParameter("nachname"));
			System.out.println("email: " + request.getParameter("email"));
			if (request.getParameterValues("selectfield") == null) {
				System.out.println("selectfield: "
						+ request.getParameterValues("selectfield"));
			} else {
				String[] s = request.getParameterValues("selectfield");
				for (int i = 0; i < s.length; i++) {
					System.out.println("selectfield[" + i + "]: " + s[i]);
				}
			}
			System.out.println("babbrechen: "
					+ request.getParameter("babbrechen"));
			System.out.println("bloeschen: "
					+ request.getParameter("bloeschen"));
			System.out.println("bspeichern: "
					+ request.getParameter("bspeichern"));

			if (request.getParameter("benutzerId") != null) {
				if (!request.getParameter("benutzerId").equals("")) {
					b = benutzerRepository.getBenutzerNachId(Integer
							.parseInt(request.getParameter("benutzerId")));
				}
			}
			request.setAttribute("benutzer", b);
			if (request.getParameter("babbrechen") != null) {
				// Abbrechen
				response.sendRedirect("BenutzerListe");
			} else if (request.getParameter("bspeichern") != null) {
				String[] grps = request.getParameterValues("selectfield");
				if (grps == null) {
					grps = new String[0];
				}

				// Speichern
				if (b == null) {

					// Check, ob die Email schon für anderen benutzer
					// eingetragen ist
					if (benutzerRepository.getBenutzerNachEmail(request
							.getParameter("email")) == null) {

						// neuen Benutzer erstellen
						try {
							// Benutzer
							b = new Benutzer();
							b.setId(-1);
							b.setNachname(request.getParameter("nachname"));
							b.setVorname(request.getParameter("vorname"));
							b.setEmail(request.getParameter("email"));
							b.setErstellt((new GregorianCalendar())
									.getTimeInMillis());
							b.setPasswort("Defaultwert: keinMöglicherHash! %&$()");
							benutzerRepository.newBenutzer(b);
							// Passwort-Link
							PwVergessenSchnittstelle.abgelaufeneLinksLoeschen();
							PwZuruecksetzenLink l;
							String alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
							Random generator = new Random();
							String random;
							do {
								random = "";
								for (int i = 0; i < 60; i++) {
									random += alphabet.charAt(generator
											.nextInt(alphabet.length()));
								}
								l = PwVergessenSchnittstelle.getLink(random);
							} while (l != null);
							l = new PwZuruecksetzenLink();
							l.random = random;
							l.benutzerId = b.getId();
							l.erstelltzeit = (new GregorianCalendar())
									.getTimeInMillis();
							PwVergessenSchnittstelle.setLink(l);
							Mail.nutzerErstellt(b.getEmail(),
												"http://" +
												request.getServerName() + (80==request.getServerPort()?"":(":"+request.getServerPort())) +
												"/ModulManagementSystem/PasswortVergessen?link=" + random);
							// Gruppen
							boolean inGroup;
							Benutzer[] mitglieder, mitgliederAlt;
							for (int i = 0; i < gruppenRepository.size(); i++) {
								inGroup = false;
								for (int j = 0; j < grps.length; j++) {
									if (grps[j].equals(""
											+ gruppenRepository.get(i).getId())) {
										inGroup = true;
										break;
									}
								}
								if (inGroup) {
									mitgliederAlt = gruppenRepository.get(i)
											.getBenutzer();
									if (mitgliederAlt == null) {
										mitgliederAlt = new Benutzer[0];
									}
									mitglieder = new Benutzer[mitgliederAlt.length + 1];
									for (int j = 0; j < mitgliederAlt.length; j++) {
										mitglieder[j] = mitgliederAlt[j];
									}
									mitglieder[mitglieder.length - 1] = b;
									gruppenRepository.get(i).setBenutzer(
											mitglieder);
									gruppenRepository
											.saveGruppe(gruppenRepository
													.get(i));
								}
							}

							// Logging (ID des geänderten Benutzers, Aktionstyp, aktueller Benutzer, Logtyp)
							new helper.Logging(""+b.getId(),"Erstellung", benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)0);
							
							response.sendRedirect("BenutzerListe");

						} catch (SQLException e) {
							new helper.Logging("Fehler F041",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
							response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F041)");
						} catch (ClassNotFoundException e) {
							new helper.Logging("Fehler F042",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
							response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F042)");
							// } catch (NoSuchAlgorithmException e) {
							// response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es gab einen Algorithmusfehler! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F043)");
						} catch (AngepassteException e) {
							response.sendRedirect(e.getMessage());
						}

						System.out.println("create");
					} else {
						new helper.Logging("Fehler F044","Emailadresse wird bereits verwendet.", benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
						response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Diese Emailadresse wird bereits verwendet! Sollte es sich um einen Fehler handeln, kontaktieren Sie bitte einen Administrator. (F044)");
					}

				} else {
					// Änderung speichern
					System.out.println("save");
					boolean inGroup;
					Benutzer[] mitglieder, mitgliederAlt;
					for (int i = 0; i < gruppenRepository.size(); i++) {
						inGroup = false;
						for (int j = 0; j < grps.length; j++) {
							if (grps[j].equals(""
									+ gruppenRepository.get(i).getId())) {
								inGroup = true;
								break;
							}
						}
						try {
							if (inGroup
									&& !gruppenRepository.get(i).inGruppe(
											b.getId())) {
								System.out.println("add user to grp "
										+ gruppenRepository.get(i).getId());
								mitgliederAlt = gruppenRepository.get(i)
										.getBenutzer();
								if (mitgliederAlt == null) {
									mitgliederAlt = new Benutzer[0];
								}
								mitglieder = new Benutzer[mitgliederAlt.length + 1];
								for (int j = 0; j < mitgliederAlt.length; j++) {
									mitglieder[j] = mitgliederAlt[j];
								}
								mitglieder[mitglieder.length - 1] = b;
								gruppenRepository.get(i)
										.setBenutzer(mitglieder);
								gruppenRepository.saveGruppe(gruppenRepository
										.get(i));
							} else if (!inGroup
									&& gruppenRepository.get(i).inGruppe(
											b.getId())) {
								System.out.println("rem user from grp "
										+ gruppenRepository.get(i).getId());
								mitgliederAlt = gruppenRepository.get(i)
										.getBenutzer();
								if (mitgliederAlt == null) {
									mitgliederAlt = new Benutzer[0];
									mitglieder = new Benutzer[0];
								} else if (mitgliederAlt.length == 0) {
									mitglieder = new Benutzer[0];
								} else {
									mitglieder = new Benutzer[mitgliederAlt.length - 1];
								}
								for (int j = 0; j < mitglieder.length; j++) {
									if (mitgliederAlt[j] != b) {
										mitglieder[j] = mitgliederAlt[j];
									} else {
										for (j = j + 1; j < mitgliederAlt.length; j++) {
											mitglieder[j - 1] = mitgliederAlt[j];
										}
										break;
									}
								}
								gruppenRepository.get(i)
										.setBenutzer(mitglieder);
								gruppenRepository.saveGruppe(gruppenRepository
										.get(i));
							}
						} catch (ClassNotFoundException e) {
							new helper.Logging("Fehler F044",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
							response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F044)");
						} catch (SQLException e) {
							new helper.Logging("Fehler F045",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
							response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F045)");
						}
					}
					try {
						if (b == super.getAktuellerBenutzer(request, response)) {
							request.getSession().setAttribute("email",
									request.getParameter("email"));
							System.out.println("akkt email geändert");
						}
						b.setNachname(request.getParameter("nachname"));
						b.setVorname(request.getParameter("vorname"));
						b.setEmail(request.getParameter("email"));
						benutzerRepository.saveBenutzer(b);
					} catch (SQLException e) {
						new helper.Logging("Fehler F046",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
						response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F046)");
					} catch (IllegalArgumentException e) {
						new helper.Logging("Fehler F049",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
						response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F049)");
					} catch (ClassNotFoundException e) {
						new helper.Logging("Fehler F0410",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
						response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F0410)");
					}
					response.sendRedirect("BenutzerListe");

					// Logging (ID des geänderten Benutzers, Aktionstyp, aktueller Benutzer, Logtyp)
					new helper.Logging(""+b.getId(),"Modifizierung", benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)0);

				}

			} else if (request.getParameter("bloeschen") != null && b != null) {
				// löschen

				
				//TODO Geht noch nicht, irgendwie wird das hier nie ausgeführt?!
				
				System.out.println("<b><i>Löschung</i></b><br><b>Löschend: </b> Irgendwas halt <br><b>Gel&ouml;scht (ID): </b>"	+ b.getId() + "<br><b>Datum: </b>"
						+ new java.text.SimpleDateFormat(
								"dd.MM.yyyy HH:mm:ss")
								.format(new java.util.Date()));
				
				
				// Logging (ID des geänderten Benutzers, Aktionstyp, aktueller Benutzer, Logtyp)
				new helper.Logging(""+b.getId(),"Löschung", benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)0);

				System.out.println("del");
				try {

					benutzerRepository.delBenutzer(b);
				} catch (SQLException e) {
					new helper.Logging("Fehler F047",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
					response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F047)");
				} catch (ClassNotFoundException e) {
					new helper.Logging("Fehler F048",e.toString(), benutzerRepository.getBenutzerNachEmail((String) request.getSession().getAttribute("email")), (byte)1);
					response.sendRedirect("Fehler?weiterleitung=BenutzerForm&fehler=Es konnte nicht auf die Datenbank zugegriffen werden! Bitte versuchen Sie es erneut oder kontaktieren Sie einen Administrator. (F048)");
				}
				response.sendRedirect("BenutzerListe");
			} else {
				// nur anzeigen
				
				RequestDispatcher view;
				view = request.getRequestDispatcher("BenutzerForm.jsp");
				view.forward(request, response);
			}
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
